<html>
<head><meta charset="utf-8"><title>Function trait constraint return lifetimes · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html">Function trait constraint return lifetimes</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="208845255"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208845255" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208845255">(Sep 02 2020 at 15:47)</a>:</h4>
<p>I'm having a problem were I need a constraint that looks like:</p>
<div class="codehilite"><pre><span></span><code>F: for&lt;&#39;b&gt; FnOnce(&amp;&#39;b SomeFixedType) -&gt; T, T: &#39;b
</code></pre></div>


<p>Where <code>SomeFixedType</code> is not generic, but the return value is. I want the returned value to have the contrained <code>'b</code> lifetime, but based on the error messages I'm seeing with simply <code>FnOnce(&amp;SomeFixedType) -&gt; T</code> as the constraint, it seems to not be able to do this. Is there a way to achieve this constraint? Some special syntax for function traits?</p>



<a name="208846236"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208846236" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208846236">(Sep 02 2020 at 15:53)</a>:</h4>
<p>The caller of your function would chose a <code>T</code>, but then it would need to be valid for all possible <code>'b</code>. The only possible lifetime for this would be <code>'static</code>: <code>T: 'static</code>.</p>



<a name="208847257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208847257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208847257">(Sep 02 2020 at 15:59)</a>:</h4>
<p>Shouldn't the 'all possible <code>'b</code>' semantics only apply to function inputs? I <em>think</em> I should be able to take any function which operates on a referenced <code>'b</code> and return something which will only be valid for the caller to use while <code>'b</code> is valid, i.e. it doesn't outlive that <code>'b</code>? Or maybe I'm wholly misinterpreting the error message I see: when I call this generic function with a <code>F: FnOnce(&amp;SomeFixedType) -&gt; T</code> constraint, I get an error at the call site complaining that the input reference lifetime (let's call it <code>'b</code> for consistency) must outlive the returned value's lifetime.</p>



<a name="208847534"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208847534" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208847534">(Sep 02 2020 at 16:01)</a>:</h4>
<p>The thing is that <code>T</code> is chosen by the caller of the function, not by the implementation.</p>



<a name="208847626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208847626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208847626">(Sep 02 2020 at 16:01)</a>:</h4>
<p>I agree, but the caller is also choosing <code>F</code>, so there should be a way to express this relationship between <code>F</code> and <code>T</code>?</p>



<a name="208847783"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208847783" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208847783">(Sep 02 2020 at 16:02)</a>:</h4>
<p>Yes, but then the caller must also choose <code>'b</code>.</p>



<a name="208848151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208848151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208848151">(Sep 02 2020 at 16:05)</a>:</h4>
<p>Okay, but then is there a correct way of taking a function that should return a value not outliving a parameter? Sorry if I'm missing something here, but that feels like it should be possible as far as lifetime checking goes.</p>



<a name="208848594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208848594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208848594">(Sep 02 2020 at 16:08)</a>:</h4>
<p>Could you give (a gist of) the function you are trying to get compiling?</p>



<a name="208850093"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208850093" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208850093">(Sep 02 2020 at 16:19)</a>:</h4>
<p>Here's a stripped down example that demonstrates the error (with rustc 1.46.0):</p>
<div class="codehilite"><pre><span></span><code>use futures::future::{Future, FutureExt, LocalBoxFuture};

trait DoThing {
    fn do_thing&lt;&#39;a, F, Fut, Ret&gt;(&amp;&#39;a mut self, f: F) -&gt; LocalBoxFuture&lt;&#39;a, Ret&gt;
    where
        F: FnOnce(&amp;mut u64) -&gt; Fut + &#39;a,
        Fut: Future&lt;Output = Ret&gt;,
    {
        async move {
            let mut t: u64 = 42;
            let ret = f(&amp;mut t).await;
            t += 100;
            ret
        }
        .boxed_local()
    }
}

impl&lt;T&gt; DoThing for T {}

async fn try_do_thing() {
    let mut v = true;
    v.do_thing(|i| async move { *i += 5; false }).await;
}
</code></pre></div>



<a name="208850402"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208850402" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208850402">(Sep 02 2020 at 16:22)</a>:</h4>
<p>Although now that I've written that out, I do realize the lifetime error :(</p>



<a name="208850493"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208850493" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208850493">(Sep 02 2020 at 16:22)</a>:</h4>
<p>In that the returned future from <code>do_thing</code> is outliving the lifetime of <code>&amp;mut t</code>.</p>



<a name="208850611"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208850611" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208850611">(Sep 02 2020 at 16:23)</a>:</h4>
<p>Or maybe that's not an error... the returned value from <code>f(&amp;mut t)</code> is awaited immediately, which should have the correct lifetime?</p>



<a name="208850709"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208850709" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208850709">(Sep 02 2020 at 16:24)</a>:</h4>
<p>Probably should have mentioned that this is all involved with async code; I have a non-async counterpart that works as expected.</p>



<a name="208859041"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208859041" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208859041">(Sep 02 2020 at 17:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="329463">Alex Franchuk</span> <a href="#narrow/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes/near/208850493">said</a>:</p>
<blockquote>
<p>In that the returned future from <code>do_thing</code> is outliving the lifetime of <code>&amp;mut t</code>.</p>
</blockquote>
<p>Yes, that is the error.<br>
<span class="user-mention silent" data-user-id="329463">Alex Franchuk</span> <a href="#narrow/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes/near/208850611">said</a>:</p>
<blockquote>
<p>Or maybe that's not an error... the returned value from <code>f(&amp;mut t)</code> is awaited immediately, which should have the correct lifetime?</p>
</blockquote>
<p>Rustc doesn't know that this is the case by looking at the signature of <code>do_thing</code>.</p>
<p>I tried if I could get it working, but it is pretty hard.</p>



<a name="208859546"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208859546" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208859546">(Sep 02 2020 at 17:31)</a>:</h4>
<p>Yeah, I've also tried a number of things (besides <code>std::mem::transmute</code>ing the lifetimes) to get it working...</p>



<a name="208860467"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/208860467" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#208860467">(Sep 02 2020 at 17:38)</a>:</h4>
<p>I think the fundamental issue here is that I'm trying to express an "at most" lifetime constraint, but I believe the rust lifetime constraints are all "at least".</p>



<a name="209048042"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Function%20trait%20constraint%20return%20lifetimes/near/209048042" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alex Franchuk <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Function.20trait.20constraint.20return.20lifetimes.html#209048042">(Sep 04 2020 at 01:47)</a>:</h4>
<p>Just to close the loop a bit here, it looks like this problem has been reported as a bug (the closest I got to something working ran into this issue): <a href="https://github.com/rust-lang/rust/issues/70263">https://github.com/rust-lang/rust/issues/70263</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>